package com.siro.auth.controller;

import com.siro.auth.base.constant.CacheConstants;
import com.siro.auth.entity.SysMenu;
import com.siro.auth.base.common.model.LoginUser;
import com.siro.auth.entity.UserInfo;
import com.siro.auth.base.common.domain.MenuTree;
import com.siro.auth.utils.RedisCache;
import com.siro.auth.base.common.domain.Result;
import com.siro.auth.entity.vo.RouterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author starsea
 * @date 2022-07-18 14:32
 */
@RestController
@RequestMapping("/api/sysUser")
public class SysLoginController {

    @Autowired
    private RedisCache redisCache;

    /**
     * 获取用户信息
     *
     * @return
     */
    @GetMapping("/getInfo")
    public Result getInfo() {
        //从Spring Security上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if (authentication == null) {
            return Result.fail().message("用户信息查询失败");
        }
        //获取用户信息
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        //用户权限集合
        List<SysMenu> permissionList = loginUser.getPermissionList();
        //获取角色权限编码字段
        Object[] roles = permissionList.stream().filter(Objects::nonNull).map(SysMenu::getCode).toArray();
        //创建用户信息对象
        UserInfo userInfo = new UserInfo(loginUser.getUserId(), loginUser.getUsername(),
                loginUser.getUser().getAvatar(), null, roles);
        //返回数据
        return Result.ok(userInfo).message("用户信息查询成功");
    }

    /**
     * 获取菜单数据
     *
     * @return
     */
    @GetMapping("/getMenuList")
    public Result getMenuList() {
        //从Spring Security上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取用户信息
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        //获取相应的权限
        List<SysMenu> permissionList = loginUser.getPermissionList();
        //筛选目录和菜单
        List<SysMenu> collect = permissionList.stream()
                .filter(item -> item != null && item.getType() != 2)
                .collect(Collectors.toList());
        //生成路由数据
        List<RouterVo> routerVoList = MenuTree.makeRouter(collect, 0L);
        //返回数据
        return Result.ok(routerVoList).message("菜单数据获取成功");
    }

    /**
     * 用户退出
     * postman测试：
     * 1. 执行用户登录请求后，在查询所有部门信息
     * 2. 执行用户退出请求，在此查询所有部门信息，预期结果是token已过期
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request, HttpServletResponse response) {
        // 获取token
        String token = request.getParameter("token");
        //如果没有从头部获取token，那么从参数里面获取
        if (ObjectUtils.isEmpty(token)) {
            token = request.getHeader("token");
        }
        // 获取用户相关信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            // 清空用户信息
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            // 清空redis里面的token
            String key = CacheConstants.LOGIN_TOKEN_KEY + token;
            redisCache.del(key);
        }
        return Result.ok().message("用户退出成功");
    }
}
